//
//  STPageTitleView.swift
//  iPhone
//
//  Created by Toj on 11/17/22.
//

import UIKit

protocol STPageTitleViewDelegate: NSObjectProtocol {
    
    // 每次点击
    func titleView(_ view: STPageTitleView, didSelect index: Int)
    // 每次点击不同Title
    func titleView(_ view: STPageTitleView, didSelected index: Int, title: String)
}

class STPageTitleView: UIView {
    
    weak var delegate: STPageTitleViewDelegate?
    
    public var selectedIndex = 0 { willSet {
        guard selectedIndex != newValue else { return }
        guard titles.count > newValue else { return }
        let selString = titles[newValue]
        delegate?.titleView(self, didSelected: newValue, title: selString)
        
        collectionView.scrollToItem(at: IndexPath(row: newValue, section: 0), at: .centeredHorizontally, animated: true)
    } }
    
    public var currentTitle: String {
        guard titles.count > selectedIndex else { return "" }
        return titles[selectedIndex]
    }
    
    public var titles: [String] = [] { didSet {
        titlesSize = [:]
        collectionView.reloadData()
    } }
    
    public var viewStyle = STPageTitleStyle() { didSet {
        setupMakeInitialize()
    } }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupMakeAddSubviews()
        setupMakeInitialize()
        setupMakeLayoutSubviews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private lazy var layout: UICollectionViewFlowLayout = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        // cell之间 垂直间距
        layout.minimumLineSpacing = 0
        // cell之间 水平间距
        layout.minimumInteritemSpacing = viewStyle.cellStyle.textSpacing
        return layout
    }()
    
    private lazy var collectionView: UICollectionView = {
        let view = UICollectionView(frame: .zero, collectionViewLayout: layout)
        view.backgroundColor = .clear
        view.scrollsToTop = false
        view.showsVerticalScrollIndicator = false
        view.showsHorizontalScrollIndicator = false
        view.contentInsetAdjustmentBehavior = .never
        view.register(STPageTitleCell.cell_class, forCellWithReuseIdentifier: STPageTitleCell.cell_identifier)
        view.dataSource = self
        view.delegate = self
        return view
    }()
    
    private(set) lazy var lineView = UIView()
    
    private var titleCell: STPageTitleCell? { willSet {
        guard let cell = newValue else { return }
        var center = lineView.center
        center.x = cell.center.x
        var frame = lineView.frame
        
        var width: CGFloat = viewStyle.lineStyle.width
        if viewStyle.lineStyle.fillType == .content {
            cell.titleLabel.sizeToFit()
            cell.layoutIfNeeded()
            width = cell.titleLabel.frame.width
        }
        else if viewStyle.lineStyle.fillType == .fill {
            if let size = titlesSize[cell.title] {
                width = size.width
            }
        } else if viewStyle.lineStyle.fillType == .fair {
            width = CGFloat.sr_width / CGFloat(titles.count)
        }
        
        frame.size.width = width
        guard titleCell != nil else {
            lineView.frame = frame
            return
        }
        
        UIView.animate(withDuration: 0.25) {
            self.lineView.frame = frame
            self.lineView.center = center
        }
    } }
    
    private var titlesSize: [String: CGSize] = [:]
    
    deinit {
        print("-->startimes: \(st_className) func: deinit")
    }
}

// MARK: - 代理事件 UICollectionViewDataSource
extension STPageTitleView: UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return titles.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifierClass: STPageTitleCell.self, for: indexPath)
        cell.title = titles[indexPath.row]
        if cell.cellStyle == nil {
            cell.cellStyle = viewStyle.cellStyle
        }
        
        cell.isSelectedTitle = selectedIndex == indexPath.row
        return cell
    }
}

// MARK: - 代理事件 UICollectionViewDelegate
extension STPageTitleView: UICollectionViewDelegate {
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let row = indexPath.row
        delegate?.titleView(self, didSelect: row)
        guard selectedIndex != row else { return }
        selectedIndex = row
        collectionView.reloadData()
    }
    
    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        guard indexPath.row == selectedIndex else { return }
        
        guard let titleCell = cell as? STPageTitleCell else { return }
        titleCell.tag = indexPath.row
        self.titleCell = titleCell
    }
}

// MARK: - 代理事件 UICollectionViewDelegateFlowLayout
extension STPageTitleView: UICollectionViewDelegateFlowLayout {
    
    // cell 大小
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let title = titles[indexPath.row]
        
        guard let titleSize = titlesSize[title] else {
            var width: CGFloat = viewStyle.cellStyle.width
            let height = collectionView.frame.height
            if viewStyle.cellStyle.fillType == .content {
                width = title.cm_stringWidth(font: viewStyle.cellStyle.textFont, maxHeight: 20) + viewStyle.lineSpacing
            }
            else if viewStyle.cellStyle.fillType == .fair {
                width = CGFloat.sr_width / CGFloat(titles.count)
            }
            let titleSize = CGSize(width: width, height: height)
            titlesSize[title] = titleSize
            return titleSize
        }
        return titleSize
    }
}

// MARK: - 初始化设置
extension STPageTitleView {
    
    private func setupMakeAddSubviews() {
        addSubview(collectionView)
        collectionView.addSubview(lineView)
        collectionView.bringSubviewToFront(lineView)
    }
    
    private func setupMakeLayoutSubviews() {
        collectionView.snp.makeConstraints { make in
            make.edges.equalTo(self)
        }
        
        var lineViewFrame = lineView.frame
        lineViewFrame.origin.y = viewStyle.height - viewStyle.lineStyle.height
        lineViewFrame.size.height = viewStyle.lineStyle.height
        lineView.frame = lineViewFrame
    }
    
    private func setupMakeInitialize() {
        layout.minimumInteritemSpacing = viewStyle.cellStyle.textSpacing
        lineView.backgroundColor = viewStyle.lineStyle.color
        collectionView.isScrollEnabled = viewStyle.isScrollEnabled
        collectionView.contentInset = UIEdgeInsets(top: 0, left: viewStyle.cellStyle.leftEdgeInset, bottom: 0, right: viewStyle.cellStyle.rightEdgeInset)
    }
}

// MARK: - STPageTitleCell
class STPageTitleCell: UICollectionViewCell {
    
    var cellStyle: STPageTitleCellStyle? { didSet {
        titleLabel.font = cellStyle?.textFont
    } }
    
    var title: String = "" { didSet {
        titleLabel.text = title
    } }
    
    var isSelectedTitle = false { willSet {
        backgroundColor = newValue ? cellStyle?.textSelectedBackgroundColor : cellStyle?.textBackgroundColor
        titleLabel.textColor = newValue ? cellStyle?.textSelectedColor : cellStyle?.textColor
    } }
    
    private(set) lazy var titleLabel: UILabel = {
        let view = UILabel()
        view.textAlignment = .center
        return view
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.addSubview(titleLabel)
        titleLabel.snp.remakeConstraints { make in
            make.center.equalTo(contentView)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        print("-->startimes: \(st_className) func: deinit")
    }
}
